<script lang="ts">
	import { throttle } from 'lodash-es';
	// 使用 Runes 的 $props 声明组件属性并设置默认值
	const {
		children,
		parentRef = $bindable(),
		index = 0,
		x = 0,
		y = 0,
		isActive = false,
		axis = 'both',
		startMove = () => {},
		onMoving = () => {},
		endMove = () => {}
	}: {
		children: any;
		parentRef: HTMLElement | null;
		index: number;
		x: number;
		y: number;
		isActive: boolean;
		axis: 'x' | 'y' | 'both';
		startMove: (index: number, startPosition: { x: number; y: number }) => void;
		onMoving: (index: number, toPosition: { x: number; y: number }) => void;
		endMove: (index: number) => void;
	} = $props();
	
	// 使用 $state 创建响应式状态
	let isDragging = $state(false);
    let currentX = 0;
	let currentY = 0;
	const mouseStartPosition = { x: 0, y: 0 };
	const startPosition = { x: 0, y: 0 };	
	let elementWidth = 0;
	let elementHeight = 0;
	let parentWidth = 0;
	let parentHeight = 0;

	// 鼠标按下事件
	const onMouseDown = (event: MouseEvent) => {
		// 仅响应左键点击
		if (event.button !== 0) return;

		event.preventDefault();
		isDragging = true;

		// 记录初始鼠标位置
		mouseStartPosition.x = event.clientX;
		mouseStartPosition.y = event.clientY;

		// 获取元素初始位置（包含滚动偏移）
		const targetEl = event.currentTarget as HTMLElement;
		elementWidth = targetEl.offsetWidth;
		elementHeight = targetEl.offsetHeight;
		parentWidth = parentRef?.scrollWidth || 0;
		parentHeight = parentRef?.scrollHeight || 0;
		startPosition.x = x;
		startPosition.y = y;

		// 触发开始拖拽事件
		startMove(index, { ...startPosition });

		// 绑定全局移动和释放事件
		window.addEventListener('mousemove', onMouseMove);
		window.addEventListener('mouseup', onMouseUp);
	};
	// 鼠标移动事件
	const onMouseMove = throttle((event: MouseEvent) => {
		if (!isDragging) return;

		event.preventDefault();
		// 根据允许的轴更新位置
		if (axis === 'x' || axis === 'both') {       
			currentX = event.clientX - mouseStartPosition.x + startPosition.x;            
			// 验证移动范围，不超过父容器
			currentX = Math.max(0, Math.min(currentX, parentWidth - elementWidth));
		}
		if (axis === 'y' || axis === 'both') {
			currentY = event.clientY - mouseStartPosition.y + startPosition.y;
			// 验证移动范围，不超过父容器
			currentY = Math.max(0, Math.min(currentY, parentHeight - elementHeight));
		}
		// 触发拖拽中事件
		onMoving(index, { x: currentX, y: currentY });
	}, 16);

	// 鼠标释放事件
	function onMouseUp() {
		isDragging = false;
		// 触发结束拖拽事件
		endMove(index);
		// 移除全局事件监听
		window.removeEventListener('mousemove', onMouseMove);
		window.removeEventListener('mouseup', onMouseUp);
	}

	// 组件卸载时清理事件监听（使用 $effect 的销毁函数）
	$effect(() => {
		return () => {
			window.removeEventListener('mousemove', onMouseMove);
			window.removeEventListener('mouseup', onMouseUp);
		};
	});
</script>

<!-- 拖拽容器 -->
<div
	class="drag-item"
	class:isActive
    class:isDragging
	style={`
		position: absolute;
		cursor: default;
		transform: translate(${x}px, ${y}px);
	`}
	onmousedown={onMouseDown}
	onkeydown={() => {}}
	role="button"
	tabindex="0"
>
	{@render children?.()}
</div>

<style lang="scss">
	.drag-item {
		z-index: 1;
        user-select:none;
	}
	.drag-item.isActive {
		z-index: 200;
	}
    .drag-item:not(.isDragging){
        transition: transform 0.2s ease;
    }
</style>
